package com.startx.core.point;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.startx.core.config.holder.ConfigHolder;
import com.startx.core.point.anotation.AccessPoint;
import com.startx.core.point.anotation.RequestMethod;
import com.startx.core.point.anotation.RequestPoint;
import com.startx.core.point.factory.PointFactory;
import com.startx.core.system.model.AccessPointTarget;
import com.startx.core.system.model.StartxConfig;
import com.startx.core.tools.ClassReader;

/**
 * 接入点初始化
 */
public class Point {
	
	/**
	 * log 工具
	 */
	private static final Logger Log = Logger.getLogger(Point.class);
	
	/**
	 * spring 上下文环境
	 */
	private static ClassPathXmlApplicationContext context;
	
	/**
	 * 启动安装AccessPoint
	 */
	public static void start() {
		
		StartxConfig config = ConfigHolder.getConfig();
		
		if(Objects.isNull(context)) {
			
			if(Objects.isNull(config.getSpringPath())) {
				throw new RuntimeException("Spring配置文件地址未设置");
			}
			
			context = new ClassPathXmlApplicationContext(config.getSpringPath());
		}
		
		if(Objects.isNull(config.getPackages())) {
			throw new RuntimeException("AccessPoint扫描路径未配置");
		}
		
		init(config);
	}

	/**
	 * 初始化AccessPoint
	 */
	private static void init(StartxConfig config) {
		List<Class<?>> classes = ClassReader.getClasses(config.getPackages());
		for (Class<?> clz : classes) {
			
			if(clz.isAnnotationPresent(AccessPoint.class)) {
				
				//反射对象
				Object target = context.getBean(clz);
				
				AccessPoint accessPoint = clz.getAnnotation(AccessPoint.class);
				String[] accessPointValues = accessPoint.value();
				Method[] declaredMethods = clz.getDeclaredMethods();
				for(Method method:declaredMethods) {
					
					if(method.isAnnotationPresent(RequestPoint.class)) {
						
						RequestPoint mapping = method.getAnnotation(RequestPoint.class);
						RequestMethod[] requestMethods = mapping.method();
						String[] mappingValues = mapping.value();
						
						if(mappingValues.length <= 0) {
							Log.error("请设置方法的RequestMapping值");
							throw new IllegalArgumentException("请设置方法的RequestMapping值");
						}
						
						StringBuffer buffer;
						
						for(RequestMethod requestMethod:requestMethods) {
							buffer = new StringBuffer();
							buffer.append(requestMethod.name().toUpperCase());
							
							for(String accessPointValue:accessPointValues) {
								
								buffer.append("_").append(accessPointValue);
								
								for(String mappingValue:mappingValues) {
									
									buffer.append(mappingValue);
									
									AccessPointTarget accessPointTarget = new AccessPointTarget();
									accessPointTarget.setMethod(method);
									accessPointTarget.setObj(target);
									accessPointTarget.setType(mapping.type());
									
									PointFactory.setAccessPoint(buffer.toString(), accessPointTarget);
								}
								
							}
							
						}
						
					}
				}
				
			}
		}
	}
	
}
